//grid width and height
var bw = 150;
var bh = 150;
//padding around grid
var p = 10;
//size of canvas
var cw = bw + (p*2) + 1;
var ch = bh + (p*2) + 1;

var canvas, context, canvasObject;
var map = [];
var mapOpp = [];

var coordIniT1= new Coordenada(33,40);
var coordIniT2= new Coordenada(167,40);
var cellWidth=50;
var cellHeight=50;
var widthT=cellWidth*2;
var heightT=cellHeight*2;
var camposT1;
var camposT2;
var opponent;
var arePlaying=false;
var gameOver=false;
var canPlay=false;

$(function() {
	canvas = $('#tablero');
	canvas.attr({width: cw * 2, height: ch});
	canvasObject = canvas.get(0);
	context = canvasObject.getContext("2d");
	
	
	drawBoard();
	initialize();
	//drawBoard(133.33, 133.33);
	
	var numNaves = 1;
	initMatrix(2, numNaves);
	
	canvas.click(function(evt) {
		evt.preventDefault();
		var rect = canvasObject.getBoundingClientRect();
	    var x=evt.clientX - rect.left;
		var y=evt.clientY - rect.top;
		for (var i=0;i<4;i++){
			//jugada en el tablero 1
			/*
			if (x>=camposT1[i].x && x<camposT1[i].x+cellWidth && y>=camposT1[i].y && y<camposT1[i].y+cellHeight)
				alert('T1 celda: '+i);
			*/
			//jugada en el tablero 2
			if (x>=camposT2[i].x && x<camposT2[i].x+cellWidth && y>=camposT2[i].y && y<camposT2[i].y+cellHeight){
				/*
				 * 0 => (0,0)
				 * 1 => (0,1)
				 * 2 => (1,0)
				 * 3 => (1,1)
				 * */
				switch (i){
					case 0:
						if (mapOpp[0][0]==0 && canPlay==true){
							if (from!=null && opponent!=null){
								mapOpp[0][0]=1;
								var imageObj = $(new Image());
								imageObj.load({x: camposT2[0].x, y: camposT2[0].y}, function(e) {
									context.drawImage(this, e.data.x, e.data.y);
								}).attr('src', 'img/waterS.png');
								canPlay=false;
								//send message to opponent
								wsclient.play(from,opponent,i);
							}
						}
						break;
					case 1:
						if (mapOpp[0][1]==0 && canPlay==true){
							if (from!=null && opponent!=null){
								mapOpp[0][1]=1;
								var imageObj = $(new Image());
								imageObj.load({x: camposT2[1].x, y: camposT2[1].y}, function(e) {
									context.drawImage(this, e.data.x, e.data.y);
								}).attr('src', 'img/waterS.png');
								canPlay=false;
								//send message to opponent
								wsclient.play(from,opponent,i);
							}
						}
						break;
					case 2:
						if (mapOpp[1][0]==0 && canPlay==true){
							if (from!=null && opponent!=null){
								mapOpp[1][0]=1;
								var imageObj = $(new Image());
								imageObj.load({x: camposT2[2].x, y: camposT2[2].y}, function(e) {
									context.drawImage(this, e.data.x, e.data.y);
								}).attr('src', 'img/waterS.png');
								canPlay=false;
								//send message to opponent
								wsclient.play(from,opponent,i);
							}
						}
						break;
					case 3:
						if (mapOpp[1][1]==0 && canPlay==true){
							if (from!=null && opponent!=null){
								mapOpp[1][1]=1;
								var imageObj = $(new Image());
								imageObj.load({x: camposT2[3].x, y: camposT2[3].y}, function(e) {
									context.drawImage(this, e.data.x, e.data.y);
								}).attr('src', 'img/waterS.png');
								canPlay=false;
								//send message to opponent
								wsclient.play(from,opponent,i);
							}
						}
						break;
				}
			}
		}
	});
});

function Coordenada(x,y){
	this.x=x;
	this.y=y;
}

function initialize(){
	//create fields
	camposT1=new Array(new Coordenada(coordIniT1.x,coordIniT1.y),new Coordenada(coordIniT1.x+cellWidth+1,coordIniT1.y),new Coordenada(coordIniT1.x,coordIniT1.y+cellHeight+1),new Coordenada(coordIniT1.x+cellWidth+1,coordIniT1.y+cellHeight+1));
	camposT2=new Array(new Coordenada(coordIniT2.x,coordIniT2.y),new Coordenada(coordIniT2.x+cellWidth+1,coordIniT2.y),new Coordenada(coordIniT2.x,coordIniT2.y+cellHeight+1),new Coordenada(coordIniT2.x+cellWidth+1,coordIniT2.y+cellHeight+1));
}

function initMatrix(square, numNaves) {
	if(square < 2)
		return;
	var i, j, x, y;
	for(i = 0; i < square; i++) {
		map[i] = [];
		mapOpp[i] = [];
		for(j = 0; j < square; j++){
			map[i][j] = 0;
			mapOpp[i][j] = 0;
		}
	}
	
	for(i = 0; i < numNaves; i++) {
		var ex = false;
		do {
			x = rand(square-1);
			y = rand(square-1);
			if(map[x][y] == 0) {
				map[x][y] = 1;
				ex = true;
			}
		} while(!ex);
	}
	
	for(i = 0; i < square; i++) {
		for(j = 0; j < square; j++) {
			var imageObj = $(new Image());
			imageObj.load({x: cellWidth*j + (map[i][j]? 37:42), y: cellHeight*i + (map[i][j]? 53:50)}, function(e) {
				context.drawImage(this, e.data.x, e.data.y);
			}).attr('src', map[i][j]? 'img/barco.png':'img/water.png');
		}
	}
	
	for(i = 0; i < square; i++) {
		for(j = 0; j < square; j++) {
			var imageObj = $(new Image());
			imageObj.load({x: cellWidth*j + 177, y: cellHeight*i + 50}, function(e) {
				context.drawImage(this, e.data.x, e.data.y);
			}).attr('src', 'img/water.png');
		}
	}
			
}

function rand(max){
    return Math.floor((Math.random()*(max+1)));
}

function drawBoard(){
	var canvas=document.getElementById("tablero");
	var context=canvas.getContext("2d");
	context.beginPath();
	//draw user board
	context.rect(coordIniT1.x,coordIniT1.y,widthT,heightT);
	context.fillStyle="#8ED6FF";
	context.fill();
	context.moveTo(coordIniT1.x,coordIniT1.y+cellHeight);
	context.lineTo(coordIniT1.x+widthT,coordIniT1.y+cellHeight);
	context.moveTo(coordIniT1.x+cellWidth,coordIniT1.y);
	context.lineTo(coordIniT1.x+cellWidth,coordIniT1.y+heightT);
	//draw opponent board
	context.rect(coordIniT2.x,coordIniT2.y,widthT,heightT);
	context.fillStyle="#8ED6FF";
	context.fill();
	context.moveTo(coordIniT2.x,coordIniT2.y+cellHeight);
	context.lineTo(coordIniT2.x+widthT,coordIniT2.y+cellHeight);
	context.moveTo(coordIniT2.x+cellWidth,coordIniT2.y);
	context.lineTo(coordIniT2.x+cellWidth,coordIniT2.y+heightT);
	context.lineWidth=2;
	context.strokeStyle = 'black';
	context.stroke();
}

var wsclient = (function() {
    var ws = null;
    var wsURI = 'ws://' + location.host  + '/hoteljava/hotelws';
    
    function connect(userName) {
        if(!userName || userName == '') {
            return;
        }
        
        if ('WebSocket' in window) {
            ws = new WebSocket(wsURI + '?userName=' + userName);
        } else if ('MozWebSocket' in window) {
            ws = new MozWebSocket(wsURI + '?userName=' + userName);
        } else {
            alert('Tu navegador no soporta WebSockets');
            return;
        }
        
        ws.onopen = function () {
            setConnected(true);
        };
        
        ws.onmessage = function (event) {
            var message = JSON.parse(event.data);
            processMessage(message);
        };
        
        ws.onclose = function () {
            setConnected(false);
            document.getElementById('userName').value = '';
        };
        
        function processMessage(message) {
           if (message.messageInfo){
        	   //make a move
        	   oppPlay(message.messageInfo);
           } else if (message.statusInfo) {
                if (message.statusInfo.status == 'CONNECTED') {
                    addOnlineUser(message.statusInfo.user);
                } else if (message.statusInfo.status == 'DISCONNECTED') {
                    removeOnlineUser(message.statusInfo.user);
                }
            } else if (message.connectionInfo) {
                var activeUsers = message.connectionInfo.activeUsers;
                for (var i=0; i<activeUsers.length; i++) {
                    addOnlineUser(activeUsers[i]);
                }
            }
        }
    }
    
    function cleanWhitespaces(text) {
        return text.replace(/\s/g,"_");
    }
    
    function oppPlay(message){
    	/*
		 * 0 => (0,0)
		 * 1 => (0,1)
		 * 2 => (1,0)
		 * 3 => (1,1)
		 * */
    	/*if (document.getElementById('me')=='Jugador 1')
    		document.getElementById('me').innerHTML=message.from;*/
		switch (message.message){
			case 0:
				if (map[0][0]==1){
					var imageObj = $(new Image());
					imageObj.load({x: camposT1[0].x, y: camposT1[0].y}, function(e) {
						context.drawImage(this, e.data.x, e.data.y);
					}).attr('src', 'img/explosion.png');
					gameOver=true;
					play(from,opponent,4);
					alert("perdiste!");
					setTimeout(function(){startNewGame();},2000);
				}else{
					var imageObj = $(new Image());
					imageObj.load({x: camposT1[0].x, y: camposT1[0].y}, function(e) {
						context.drawImage(this, e.data.x, e.data.y);
					}).attr('src', 'img/waterS.png');
					canPlay=true;
				}
				break;
			case 1:
				if (map[0][1]==1){
					var imageObj = $(new Image());
					imageObj.load({x: camposT1[1].x, y: camposT1[1].y}, function(e) {
						context.drawImage(this, e.data.x, e.data.y);
					}).attr('src', 'img/explosion.png');
					gameOver=true;
					play(from,opponent,4);
					alert("perdiste!");
					setTimeout(function(){startNewGame();},2000);
				}else{
					var imageObj = $(new Image());
					imageObj.load({x: camposT1[1].x, y: camposT1[1].y}, function(e) {
						context.drawImage(this, e.data.x, e.data.y);
					}).attr('src', 'img/waterS.png');
					canPlay=true;
				}
				break;
			case 2:
				if (map[1][0]==1){
					var imageObj = $(new Image());
					imageObj.load({x: camposT1[2].x, y: camposT1[2].y}, function(e) {
						context.drawImage(this, e.data.x, e.data.y);
					}).attr('src', 'img/explosion.png');
					gameOver=true;
					play(from,opponent,4);
					alert("perdiste!");
					setTimeout(function(){startNewGame();},2000);
				}else{
					var imageObj = $(new Image());
					imageObj.load({x: camposT1[2].x, y: camposT1[2].y}, function(e) {
						context.drawImage(this, e.data.x, e.data.y);
					}).attr('src', 'img/waterS.png');
					canPlay=true;
				}
				break;
			case 3:
				if (map[1][1]==1){
					var imageObj = $(new Image());
					imageObj.load({x: camposT1[3].x, y: camposT1[3].y}, function(e) {
						context.drawImage(this, e.data.x, e.data.y);
					}).attr('src', 'img/explosion.png');
					gameOver=true;
					play(from,opponent,4);
					alert("perdiste!");
					setTimeout(function(){startNewGame();},2000);
				}else{
					var imageObj = $(new Image());
					imageObj.load({x: camposT1[3].x, y: camposT1[3].y}, function(e) {
						context.drawImage(this, e.data.x, e.data.y);
					}).attr('src', 'img/waterS.png');
					canPlay=true;
				}
				break;
			case 4:
				alert("Ganaste!");
				startNewGame();
				break;
			case 5://can you play?
				if (arePlaying)//no
					play(from,opponent,6);
				else{//yes
					opponent=cleanWhitespaces(message.from);
					arePlaying=true;
					gameOver=false;
					canPlay=false;
					document.getElementById('me').innerHTML=from;
		    		document.getElementById('other').innerHTML=opponent;
					play(from,opponent,7);
				}
				break;
			case 6:
				break;
			case 7://game confirmation
				document.getElementById('me').innerHTML=from;
	    		document.getElementById('other').innerHTML=opponent;
	    		arePlaying=true;
	    		gameOver=false;
	    		canPlay=true;
				break;
		}
    }
    
    function play(sender, receiver, message){
    	if (ws != null){
    		ws.send(JSON.stringify({messageInfo : {from : sender, to : receiver, message : message}}));
    	}
    }
    
    function disconnect() {
        if (ws != null) {
            ws.close();
            ws = null;
        }
        setConnected(false);
    }
    
    function setConnected(connected) {
        document.getElementById('connect').disabled = connected;
        document.getElementById('disconnect').disabled = !connected;
        cleanConnectedUsers();
        if (connected) {
            updateUserConnected();
        } else {
            updateUserDisconnected();
        }
    }
    
    function updateUserConnected() {
        var inputUsername = $('#userName');
        var onLineUserName = $('.onLineUserName');
        onLineUserName.html(inputUsername.val());
        inputUsername.css({display:'none'});
        onLineUserName.css({visibility:'visible'});
        $('#status').html('Conectado');
        $('#status').attr({class : 'connected'});
        $('#onLineUsersPanel').css({visibility:'visible'});
        from=inputUsername.val();
        $('me').html(from);
    }

    function updateUserDisconnected() {
        $('.onLineUserName').css({visibility:'hidden'});
        $('#userName').css({display:''});
        $('#status').html('Desconectado');
        $('#status').attr({class : 'disconnected'});
        $('#onLineUsersPanel').css({visibility:'hidden'});
    }
    
    function cleanConnectedUsers() {
        $('#onlineUsers').html('');
    }
    
    /********* usuarios conectados *******/
    function addOnlineUser(userName) {
        var newOnlineUser = createOnlineUser(userName);
        newOnlineUser.appendTo($('#onlineUsers'));
        $('#onlineUsers li').click(function(){
        	if (!arePlaying){
        		opponent=$(this).text();
        		play(from,opponent,5);
        	}
    	});
    }

    function removeOnlineUser(userName) {
        $('#onlineUsers > li').each(function (index, elem) {
            if (elem.id == userName + 'onlineuser') {
                $(elem).remove();
            }
        });
    }

    function createOnlineUser(userName) {
        var link = $(document.createElement('a'));
        link.html(userName);        
        var li = $(document.createElement('li'));
        li.attr({id : (userName + 'onlineuser')});
        link.appendTo(li);
        return li;
    }
    
    function startNewGame(){
    	gameOver=false;
    	arePlaying=false;
    	canPlay=false;
    	document.getElementById('me').innerHTML="Jugador 1";
		document.getElementById('other').innerHTML="Jugador 2";
    	initMatrix(2,1);
    	canvas = $('#tablero');
    	canvas.attr({width: cw * 2, height: ch});
    	canvasObject = canvas.get(0);
    	context = canvasObject.getContext("2d");
    	context.clearRect(0, 0, canvas.width, canvas.height);
    	drawBoard();
    }
    
    // metodos publicos
    return {
        connect : connect,
        disconnect : disconnect,
        play: play
    };
})();
